package microcredit.gui.table;

import java.awt.Color;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

import javax.swing.ImageIcon;

import microcredit.model.MemberToLoanEntry;


public abstract class EnumBeanTableModel<E, C extends Enum<?>> {

	private BeanTableModel<E> delegate;
	
	public EnumBeanTableModel() {
	}
	
	private C[] cachedEnumValues;
	
	@SuppressWarnings("unchecked")
	public final C[] getEnumValues() {
		if (cachedEnumValues == null) {
			Type type = getClass().getGenericSuperclass();
			Type enumType = ((ParameterizedType)type).getActualTypeArguments()[1];
			Class<?> c = (Class<?>)enumType;
			try {
				Method m = c.getMethod("values");
				m.setAccessible(true);
				cachedEnumValues = (C[])m.invoke(null);
			} catch (Exception e) {
				throw new RuntimeException(e);
			}
		}
		return cachedEnumValues;
	}
	
	protected C getSortColumn() {
		return null;
	}
	
	protected void fireUpdated(MemberToLoanEntry o, Enum<?>... columns) {
		int index = 0;
		int rowIndex = getDelegate().getBeans().indexOf(o);
		for (Enum<?> searchEnum : getEnumValues()) {
			for (Enum<?> findEnum : columns) {
				if (searchEnum == findEnum) {
					getDelegate().fireTableCellUpdated(rowIndex, getDelegate().getStartIndex() + index);
				}
			}
			index++;
		}
	}
	
	protected final void setDelegate(BeanTableModel<E> delegate) {
		this.delegate = delegate;
	}
	protected final BeanTableModel<E> getDelegate() {
		return delegate;
	}
	
	protected abstract Object getValue(E o, C column);
	
	protected abstract String getName(C column);
	
	protected Class<?> getValueClass(C column) {return String.class;};
	
	protected void setValue(E o, Object value, C column){};
	
	protected Object getFormat(E o, C column) {
		return null;
	}
	
	protected Color getBackground(E o, C column) {
		return null;
	}
	
	protected Color getForeground(E o, C column) {
		return null;
	}
	
	protected int getWidth(C column) {
		return -1;
	}
	
	protected boolean isEditable(E o, C column) {
		return false;
	}
	protected boolean isBold(E o, C column) {
		return false;
	}
	
	protected ImageIcon getRowIcon(E o) {
		return null;
	}
	
	public ImageIcon getRowIcon() {
		return null;
	}
	
}
